package com.parking.mgr.useraccount.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.parking.mgr.common.constant.CommonConstant;
import com.parking.mgr.common.enums.CommonStatusEnum;
import com.parking.mgr.common.exception.ServiceException;
import com.parking.mgr.common.exception.enums.CommonExceptionEnum;
import com.parking.mgr.common.exception.enums.DeleteUpdateExceptionEnums;
import com.parking.mgr.common.factory.PageFactory;
import com.parking.mgr.common.pojo.base.entity.BaseEntity;
import com.parking.mgr.common.util.IdUtils;
import com.parking.mgr.useraccount.facede.BasicMenuServiceFacede;
import com.parking.mgr.useraccount.model.entity.BasicRoleEntity;
import com.parking.mgr.useraccount.model.entity.BasicRoleMenuEntity;
import com.parking.mgr.useraccount.model.mapper.BasicRoleMapper;
import com.parking.mgr.useraccount.model.mapper.BasicRoleMenuMapper;
import com.parking.mgr.useraccount.model.mapstruct.BasicRoleMenuMapStruct;
import com.parking.mgr.useraccount.model.param.BasicRoleMenuParam;
import com.parking.mgr.useraccount.model.vo.BasicRoleMenuVO;
import com.parking.mgr.useraccount.service.BasicRoleMenuService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * @ClassName BasicRoleMenuServiceImpl
 * @Description TODO
 * @Auther: shilintao
 * @Date: 2023/5/30
 */

@Service
public class BasicRoleMenuServiceImpl extends ServiceImpl<BasicRoleMenuMapper, BasicRoleMenuEntity> implements BasicRoleMenuService {


    @Resource
    private BasicMenuServiceFacede basicMenuServiceFacede;

    @Resource
    private BasicRoleMenuMapper basicRoleMenuMapper;

    @Resource
    private BasicRoleMapper basicRoleMapper;

    @Resource
    private BasicRoleMenuMapStruct basicRoleMenuMapStruct;


    @Override
    public IPage<BasicRoleMenuVO> list(BasicRoleMenuParam basicRoleMenuParam) {
        LambdaQueryWrapper<BasicRoleMenuEntity> queryWrapper = new LambdaQueryWrapper<>();
        if (ObjectUtil.isNotNull(basicRoleMenuParam)) {
            if (ObjectUtil.isNotNull(basicRoleMenuParam.getFkBasicRoleId())) {
                queryWrapper.eq(BasicRoleMenuEntity::getFkBasicRoleId, basicRoleMenuParam.getFkBasicRoleId());
            }
        }
//        queryWrapper.eq(BasicRoleMenuEntity::getFEnableState,CommonStatusEnum.ENABLE.getCode());
        // 根据排序升序排序，序号越小越在前
        queryWrapper.orderByAsc(BasicRoleMenuEntity::getFInsertTimeMillis);

        Page<BasicRoleMenuEntity> page = PageFactory.defaultPage(basicRoleMenuParam.getPageSize(), basicRoleMenuParam.getCurrPage());
        IPage<BasicRoleMenuVO> roleMenuPageVO = basicRoleMenuMapStruct.entity2VO(this.page(page, queryWrapper));
        return roleMenuPageVO;
    }

    @Override
    public IPage<BasicRoleMenuVO> listEnable(BasicRoleMenuParam basicRoleMenuParam) {
        LambdaQueryWrapper<BasicRoleMenuEntity> queryWrapper = new LambdaQueryWrapper<>();
        if (ObjectUtil.isNotNull(basicRoleMenuParam)) {
            if (ObjectUtil.isNotNull(basicRoleMenuParam.getFkBasicRoleId())) {
                queryWrapper.eq(BasicRoleMenuEntity::getFkBasicRoleId, basicRoleMenuParam.getFkBasicRoleId());
            }
        }
        queryWrapper.eq(BasicRoleMenuEntity::getFEnableState, CommonStatusEnum.ENABLE.getCode());
        // 根据排序升序排序，序号越小越在前
        queryWrapper.orderByAsc(BasicRoleMenuEntity::getFInsertTimeMillis);

        Page<BasicRoleMenuEntity> page = PageFactory.defaultPage(basicRoleMenuParam.getPageSize(), basicRoleMenuParam.getCurrPage());
        IPage<BasicRoleMenuVO> roleMenuPageVO = basicRoleMenuMapStruct.entity2VO(this.page(page, queryWrapper));
        return roleMenuPageVO;
    }

    @Override
    public void add(BasicRoleMenuParam basicRoleMenuParam) {
        String roleId = basicRoleMenuParam.getFkBasicRoleId();
        BasicRoleEntity basicRoleEntity = this.getRoleById(roleId);
        getAssignMenuByFkBasicRoleId(roleId);
        ArrayList<String> roleMenuIds = basicRoleMenuParam.getFkBasicMenuIds();
        for (String roleMenuId : roleMenuIds) {
            BasicRoleMenuEntity basicRoleMenuEntity = new BasicRoleMenuEntity();
            basicRoleMenuEntity.setFkBasicRoleId(roleId);
            basicRoleMenuEntity.setFkBasicMenuId(roleMenuId);
            //设置启用状态
            basicRoleMenuEntity.setFEnableState(CommonStatusEnum.ENABLE.getCode());
            basicRoleMenuEntity.setId(IdUtils.getId());
            this.save(basicRoleMenuEntity);
        }

    }

    @Override
    public void delete(Collection<String> ids) {
        for (String id : ids) {
            BasicRoleMenuEntity basicRoleMenuEntity = this.basicRoleMenuMapper.selectById(id);
            if (ObjectUtil.isNull(basicRoleMenuEntity)) {
                throw new ServiceException(CommonExceptionEnum.DATA_NOT_EXIST.getMessage());

            }
            if (ObjectUtil.equals(CommonConstant.CAN_DELETE, basicRoleMenuEntity.getFCanDelete())) {
                this.removeById(id);
            } else {
                throw new ServiceException(DeleteUpdateExceptionEnums.CAN_NOT_DELETE.getMessage());
            }
        }
    }


    @Override
    public void edit(BasicRoleMenuParam basicRoleMenuParam) {
        // 参数校验
        checkParam(basicRoleMenuParam, true);
        // 修改的角色菜单旧数据
        BasicRoleMenuEntity basicRoleMenuEntity = this.basicRoleMenuMapper.selectById(basicRoleMenuParam.getId());
        if (ObjectUtil.isNull(basicRoleMenuEntity)) {
            throw new ServiceException(CommonExceptionEnum.I18N_MESSAGE_DATA_NOT_EXIST.getMessage());

        }
//        BasicRoleMenuEntity currentRoleMenu = this.queryRoleMenun(basicRoleMenuParam);
        if (ObjectUtil.equals(CommonConstant.CAN_UPDATE, basicRoleMenuEntity.getFCanUpdate())) {
            BeanUtil.copyProperties(basicRoleMenuParam, basicRoleMenuEntity);
            basicRoleMenuMapper.updateById(basicRoleMenuEntity);
        } else {
            throw new ServiceException(DeleteUpdateExceptionEnums.I18N_MESSAGE_CAN_NOT_UPDATE.getMessage());
        }
    }

    /**
     * 根据fkBasicRoleId获取角色已分配的菜单 ，并通过其id删除该角色已分配的菜单
     *
     * @param fkBasicRoleId
     */
    public void getAssignMenuByFkBasicRoleId(String fkBasicRoleId) {
        LambdaQueryWrapper<BasicRoleMenuEntity> queryWrapper = new LambdaQueryWrapper<BasicRoleMenuEntity>()
                .eq(BasicRoleMenuEntity::getFkBasicRoleId, fkBasicRoleId);
        List<BasicRoleMenuEntity> assignMenuIdEntityList = this.list(queryWrapper);
        List<String> assignMenuIdList = new ArrayList<>();
        for (BasicRoleMenuEntity assignMenuId : assignMenuIdEntityList) {
            assignMenuIdList.add(assignMenuId.getId());
        }
        this.removeByIds(assignMenuIdList);
    }

    /**
     * 根据fkBasicRoleId获取菜单角色已分配菜单id集合
     *
     * @param fkBasicRoleId
     * @return
     */
    @Override
    public List<String> getAssignMenuIdListByRoleId(String fkBasicRoleId) {
        LambdaQueryWrapper<BasicRoleMenuEntity> queryWrapper = new LambdaQueryWrapper<BasicRoleMenuEntity>()
                .eq(BasicRoleMenuEntity::getFkBasicRoleId, fkBasicRoleId);
        List<BasicRoleMenuEntity> assignMenuIdEntityList = this.list(queryWrapper);
        List<String> assignMenuIdList = new ArrayList<>();
        for (BasicRoleMenuEntity assignMenuId : assignMenuIdEntityList) {
            assignMenuIdList.add(String.valueOf(assignMenuId.getFkBasicMenuId()));
        }
        return assignMenuIdList;
    }

    @Override
    public List<String> getRoleUserMenuList(List<String> userRoleIds) {
        LambdaQueryWrapper<BasicRoleMenuEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(BasicRoleMenuEntity::getFkBasicRoleId, userRoleIds).eq(BaseEntity::getFEnableState, CommonStatusEnum.ENABLE.getCode());
        List<BasicRoleMenuEntity> roleMenuEntityList = this.list(queryWrapper);
        if (CollectionUtil.isEmpty(roleMenuEntityList)) {
            throw new ServiceException(CommonExceptionEnum.DATA_NOT_EXIST.getMessage());
        }

        // 获取所属角色功能菜单ID列表
        List<String> roleMenuIds = new ArrayList<>(roleMenuEntityList.size());
        for (BasicRoleMenuEntity roleMenuEntity : roleMenuEntityList) {
            roleMenuIds.add(roleMenuEntity.getFkBasicMenuId());
        }

        // 获取功能菜单URL
        return basicMenuServiceFacede.getMenuUrlByMenuIds(roleMenuIds);
    }

    @Override
    public List<String> getRoleMenuListByRoleId(String roleId) {
        LambdaQueryWrapper<BasicRoleMenuEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(BasicRoleMenuEntity::getFkBasicRoleId, roleId)
                .eq(BaseEntity::getFEnableState, CommonStatusEnum.ENABLE.getCode());

        List<BasicRoleMenuEntity> roleMenuEntityList = basicRoleMenuMapper.selectList(queryWrapper);

        if (CollectionUtil.isNotEmpty(roleMenuEntityList)) {
            List<String> menuIds = new ArrayList<>(roleMenuEntityList.size());
            for (BasicRoleMenuEntity roleMenuEntity : roleMenuEntityList) {
                menuIds.add(roleMenuEntity.getFkBasicMenuId());
            }
            return menuIds;
        } else {
            return null;
        }

    }

    /**
     * 参数校验
     *
     * @param basicRoleMenuParam
     */
    private void checkParam(BasicRoleMenuParam basicRoleMenuParam, boolean isExcludeSelf) {
        String id = basicRoleMenuParam.getId();
        LambdaQueryWrapper<BasicRoleMenuEntity> queryWrapperById = new LambdaQueryWrapper<>();
        queryWrapperById.eq(BasicRoleMenuEntity::getId, id).ne(BasicRoleMenuEntity::getFEnableState, CommonStatusEnum.DISABLE.getCode());
        if (isExcludeSelf) {
            queryWrapperById.ne(BasicRoleMenuEntity::getId, id);
        }
    }

    /**
     * 获取角色可分配菜单数据
     *
     * @param basicRoleMenuParam
     * @return
     */
    private BasicRoleMenuEntity queryRoleMenun(BasicRoleMenuParam basicRoleMenuParam) {
        BasicRoleMenuEntity basicRoleMenuEntity = this.getById(basicRoleMenuParam.getId());
        if (ObjectUtil.isNull(basicRoleMenuEntity)) {
            throw new ServiceException(CommonExceptionEnum.DATA_NOT_EXIST.getMessage());
        }
        return basicRoleMenuEntity;
    }

    /**
     * 通过id获取角色数据
     *
     * @param id
     * @return
     */
    private BasicRoleEntity getRoleById(String id) {
        BasicRoleEntity basicRoleEntity = basicRoleMapper.selectOne(new LambdaQueryWrapper<BasicRoleEntity>().
                eq(BasicRoleEntity::getId, id));
        if (ObjectUtil.isNull(basicRoleEntity)) {
            throw new ServiceException(CommonExceptionEnum.DATA_NOT_EXIST.getMessage());
        }
        return basicRoleEntity;
    }

}
